简介
Microsoft的管理控制台没有正确地处理XML的外部实体引用导致可以信息泄露,下载目标机器的文件
CVE编号: CVE-2017-8710
影响系统
Windows 7 for 32-bit Systems Service Pack 1
Windows 7 for x64-based Systems Service Pack 1
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)
Windows Server 2008 for Itanium-Based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)
Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
分析环境及工具
Windows 7 sp1
windbg
ida
wireshark
漏洞复现
poc中有两个文件poc.msc和payload.dtd
利用流程:受害者打开poc.msc,触发外部实体对象解析,从攻击者服务器下载payload.dtd,再解析payload.dtd,最后以GET的方式发送file的内容到攻击者服务器
poc.msc如下:
1 |
|
payload.dtd如下:
1 |
|
将ip和port改为自己设定的值,并在web根目录放置payload.dtd文件即可
服务器使用python搭建一个简易服务器,payload.dtd放在当前目录即可,打开poc.msc即可收到回应(虽然报错,但是执行成功)
而服务器收到的内容正是C:\Windows\msdfmap.ini的内容
漏洞分析
首先定位漏洞程序:打开procexp,之后双击poc.msc文件进行观察,发现启动的是mmc.exe程序
用od运行mmc.exe并附带参数,弹框后暂停程序,进行栈回溯
再向下一点也可以找到打开文件的函数
在这两个打开文件的函数下断点,实际断下来的是CAMCMultiDocTemplate::OpenDocumentFile,
之后慢慢跟,中途会出现程序跑飞了,下次下个断点步入就行,之后跟到了CXMLDocument::ScLoad函数里面,发现调用了msxml3模块里面的函数
由于od看不到符号,改用windbg,可以看到调用了Document::Load
之后调用msxml3!Document::run
,就发出了tcp请求
1 | 0:000> p |
其实这里已经到达了解析执行xml里面的内容,那么出的问题就是上一层的函数
1 | 0:000> kv |
在ida查看:在mmc!CAMCDoc::ScOnOpenDocument
中调用了mmc!CConsoleFilePersistor::ScLoadConsole
之后在ScOnOpenDocument中直接调用了ScLoadXMLDocumentFromFile解析xml文档,对外部实体没有检测
但是我在win10下调试的时候,发现mmc根本就不打开xml文档
下面出于学习的目的,跟着xml的一个解析过程
跟踪对xml外部实体的解析过程
接着就是利用GetNextToken不断循环读取xml文件中的值进行解析
1 | 0:000> p |
之后最终调用的是XMLParser::LoadEntity
之后是XMLParser::PushURL再到URLStream::Open
先检测一下是不是file类型的url(准确点应该是检测file协议的)
URLStream::OpenURL到urlmon!CUrlMon::BindToStorage到urlmon!CUrlMon::StartBinding到urlmon!CBinding::StartBinding再到urlmon!CTransaction::StartEx 到urlmon!COInetProt::StartEx到urlmon!CTransaction::CompleteOperation,最后在CompleteOperation真正发出请求
漏洞修补
通过对比修补后的程序
修改的位置在CXMLDocument::ScCoCreate
在我们之前的堆栈中是看不到这个函数的(下面为未修补的程序的堆栈情况)
1 | 0:000> kv |
我调试修补后的程序,发现ScCoCreate之后就退出mmc了,而没有去调用mmc!CConsoleFilePersistor::ScLoadXMLDocumentFromFile了
1 | 0:000> kv |
所以判断是在ScCoCreate里面
可以看到如果不满足条件就直接退出了
而且在ida也明显看到了ProhibitDTD,禁止dtd文件
整个执行路径如下两图
所以微软修补方法是:在ScCoCreate函数里面判断,禁止dtd文件
漏洞检测
直接阻止含ENTITY外部实体声明的msc文件